﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
using System.Diagnostics;
using System.Windows;
using System.IO;
using Microsoft.Scripting.Hosting;
using IronPython.Runtime;

namespace WebPythonHost
{
  class PythonHost
  {
    public PythonHost(string knowledge, string test_knowledge, string executor_code)
    {
      var engine = Python.CreateEngine();

      var source = engine.CreateScriptSourceFromString(executor_code);

      var scope = engine.CreateScope();
      scope.SetVariable("knowledge_yaml", knowledge);
      scope.SetVariable("test_knowledge_yaml", test_knowledge);

      var result = source.Execute(scope);

      this.engine = engine;
      this.scope = scope;
    }
    ScriptEngine engine;
    ScriptScope scope;

    public object ExecuteKnowledgePiece(string alias, object parameters)
    {
      var method = this.scope.GetVariable("execute_knowledge_piece_wrapper");
      var result = method(alias, parameters);
      return result;
    }

    public static void Test()
    {
      //Some of the things you'd do with LINQ can be done with list comprehensions:

      //[myFunc(i) for i in numbers if i > 3] 
      //Or you can use map, reduce, and filter:

      //map(myFunc, filter(lambda x: x > 3, numbers)) 
      //But list comprehensions are much more "Pythonic" than using the functional programming constructs. For reducing things, consider using "".join or sum.
      //        And you can check the truth value of entire iterables by using any and all

      //Just remember these translations:

      //Select -> map 
      //Where -> filter 
      //Aggregate -> reduce 

      try
      {

        var engine = Python.CreateEngine();
        var scope = engine.CreateScope();

        var points = new[] { 1, 2, 4, 7, 10, 2.0, 3.1, 0 };

        scope.SetVariable("points", points);

        var knowledge = new StreamReader(Application.GetResourceStream(new Uri("knowledge.yaml", UriKind.RelativeOrAbsolute)).Stream).ReadToEnd();

        scope.SetVariable("knowledge", knowledge);

        string code = @"
try:
  import yaml
  result = yaml.load(knowledge)
except Exception, exc:
  try:
    import traceback
    result = traceback.format_exc()
  except Exception, exc2:
    result = 'Failed to get traceback for %s, because %s happened' % (str(exc), str(exc2))
result
";

        var source = engine.CreateScriptSourceFromString(code);
        var result = source.Execute(scope);

      }
      catch (Exception exc)
      {
        Trace.WriteLine(exc);
      }

    }


  }
}
